home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 May: Tool Chest / Developer CD Series Tool Chest (Apple Computer)(May 1999).iso / Tool Chest / OS Utilities / jGNE Helper / jGNE Helper.c < prev    next >
Encoding:
Text File  |  1996-01-09  |  4.6 KB  |  184 lines  |  [TEXT/ttxt]

  1.     //
  2.     //    This is "jGNE Helper", formerly a monthly posting to
  3.     //    the Usenet newsgroup alt.sources.mac.
  4.     //    It provides an example for INIT programmers
  5.     //    interested in filtering events before they are handed to
  6.     //    applications calling GetNextEvent (which is called by
  7.     //    WaitNextEvent).
  8.     //    
  9.     //    The jGNE filter is the Apple-sanctioned method for
  10.     //    filtering events. It is possible to patch event traps. It
  11.     //    is sometimes even advisable. But since the jGNE filter is
  12.     //    the sanctioned method, one ought to attempt to use it
  13.     //    before patching traps.
  14.     //
  15.     //    Prospective users of this code should know that the
  16.     //    plan of record for Copland does not include support
  17.     //    for jGNEFilter. However, it is likely that Copland
  18.     //    will include some form of global event filtering service.
  19.     //    Carefully isolate your use of this code and you may
  20.     //    be able to make the move to Copland without too much
  21.     //    pain.
  22.     //
  23.     //    This code sample has a specific conflict with older
  24.     //    versions of PopChar. Newer versions of PopChar have a fix
  25.     //    which makes them compatible with this code. Users of older
  26.     //    versions of PopChar should probably upgrade to the current
  27.     //    version anyway -- this is a very old conflict. The conflict
  28.     //    manifests itself by rendering a good portion of the screen
  29.     //    "impervious" to clicks unless the option key is held down.
  30.     //    
  31.     //    This version of jGNE Helper was built with both Symantec
  32.     //  THINK C 7 and Metrowerks CodeWarrior CW7 for 68K machines.
  33.     //    It's entirely possible to write a native jGNEFilter. I've
  34.     //    even done it before. However, it hasn't occurred to me how
  35.     //    to fit a native filter into the context of this sample.
  36.     //    
  37.     //    For further info on the jGNE filter, consult your Technotes.
  38.     //
  39.  
  40. #ifndef THINK_C
  41. #    ifndef __MWERKS__
  42. #        error unknown compiler
  43. #    endif
  44. #endif
  45.  
  46. #define OLDROUTINENAMES            0
  47. #define OLDROUTINELOCATIONS        0
  48.  
  49. #ifndef __RESOURCES__
  50. #    include <Resources.h>
  51. #endif
  52.  
  53. #ifndef __MEMORY__
  54. #    include <Memory.h>
  55. #endif
  56.  
  57. #ifndef __EVENTS__
  58. #    include <Events.h>
  59. #endif
  60.  
  61. #ifndef __SETUPA4__
  62. #    include <SetUpA4.h>
  63. #endif
  64.  
  65. #ifndef __LOWMEM__
  66. #    include <LowMem.h>
  67. #endif
  68.  
  69.     //
  70.     //    This example filter simply watches for clicks
  71.     //    with the command, option, and control keys held
  72.     //    down. If it finds any, it beeps and returns a
  73.     //    value which indicates the event should not be
  74.     //    passed to the application which called GNE.
  75.     //
  76.  
  77. static Boolean myGNE (EventRecord *event, Boolean preResult)
  78. {
  79.     Boolean postResult = preResult;
  80.  
  81.     if (preResult)
  82.     {
  83.         if (event->what == mouseDown)
  84.         {
  85.             if (event->modifiers & cmdKey)
  86.             {
  87.                 if (event->modifiers & optionKey)
  88.                 {
  89.                     if (event->modifiers & controlKey)
  90.                     {
  91.                         SysBeep (10);
  92.                         postResult = false;
  93.                     }
  94.                 }
  95.             }
  96.         }
  97.     }
  98.  
  99.     return postResult;
  100. }
  101.  
  102. static void        *gOldJGNE;
  103. static Boolean    inJGNE;
  104.  
  105. #if defined (THINK_C)
  106.  
  107. static pascal void myJGNE (void)
  108. {
  109.     asm
  110.     {
  111.             MOVE.L        A1,A0            // save event record pointer from __GetA4
  112.             JSR            __GetA4            // point A1 at our A4
  113.             MOVE.L        A4,-(A7)        // save old A4
  114.             MOVE.L        (A1),A4            // get new A4
  115.             MOVE.L        A0,A1            // restore old A1
  116.  
  117. #elif defined (__MWERKS__)
  118.  
  119. static pascal asm void myJGNE (void)
  120. {
  121.             MOVE.L        D0,A0            // save pre-result from SetUpA4
  122.             JSR            SetUpA4            // fix A4, stomp D0
  123.             MOVE.L        D0,-(A7)        // save old A4
  124.             MOVE.L        A0,D0            // restore pre-result
  125. #endif
  126.  
  127.             TST.B        inJGNE            // is myJGNE busy?
  128.             BNE            @1                // yes, so bail
  129.             MOVE.B        #true,inJGNE    // mark myJGNE busy
  130.             MOVE.W        D0,-(A7)        // push pre-result
  131.             MOVE.L        A1,-(A7)        // push event record pointer
  132.             JSR            myGNE            // do the real work
  133.             MOVE.L        (A7)+,A1        // restore event record pointer
  134.             ADDQ.L        #2,A7            // pop pre-result; post-result in D0
  135.             ASL.W        #8,D0            // bump C boolean to Lisa
  136.             MOVE.W        D0,8(A7)        // stash result where caller expects it
  137.             MOVE.B        #false,inJGNE    // mark myJGNE not busy
  138. @1:
  139.             MOVE.L        gOldJGNE,A0        // get previous jGNE
  140.  
  141.             MOVE.L        (A7)+,A4        // restore A4
  142.             MOVE.L        A0,-(A7)        // return to previous jGNE
  143. #if defined (THINK_C)
  144.         }
  145. #elif defined (__MWERKS__)
  146.             RTS
  147. #endif
  148. }
  149.  
  150. #if defined (__MWERKS__)
  151. #    include <A4Stuff.h>
  152. #elif defined (THINK_C)
  153.     pascal void * GetA0 (void) = { 0x2E88 };
  154. #endif
  155.  
  156. void main (void)
  157. {
  158. #if defined (__MWERKS__)
  159.     void __Startup__ (void);
  160.     long oldA4 = SetCurrentA4 ( );
  161.     RememberA4 ( );
  162.     DetachResource (RecoverHandle ((Ptr) __Startup__));
  163. #elif defined (THINK_C)
  164.     void *me = GetA0 ( );
  165.     RememberA0 ( );
  166.     DetachResource (RecoverHandle (me));
  167.     SetUpA4 ( );
  168. #endif
  169.  
  170.     gOldJGNE = LMGetGNEFilter ( );
  171.  
  172. #if defined (__MWERKS__)
  173.     LMSetGNEFilter (myJGNE);
  174. #elif defined (THINK_C)
  175.     LMSetGNEFilter ((ProcPtr) myJGNE);
  176. #endif
  177.  
  178. #if defined (__MWERKS__)
  179.     SetA4 (oldA4);
  180. #elif defined (THINK_C)
  181.     RestoreA4 ( );
  182. #endif
  183. }
  184.